package domain

import (
	"gluenet/internal/glue-srvp/domain/aggregate"
	"gluenet/internal/glue-srvp/domain/vo"
	"gluenet/internal/pkg/infra"
	"gluenet/internal/pkg/infra/prepare"
)

// 创建对象，并把对象放入依赖池，架构自动构建依赖
func init() {
	prepare.RegisterService(func() {
		domain := NewAgentDomain()
		prepare.InjectDependency(func() *Agent {
			return domain
		})
	})
}

// Agent领域，所有agent对外提供服务都在这里
type Agent struct {
	AgentFactory *aggregate.AgentFactory
}

// UnRegister agent注销，agent注销时调用
func (r *Agent) UnRegister(guid string) error {
	return r.AgentFactory.UnRegister(guid)
}

// Register agent注册和断线重连
func (r *Agent) Register(req vo.AgentRegisterReq) (*vo.AgentRegisterRes, error) {
	ag, err := r.AgentFactory.Register(req)
	if err != nil {
		return nil, err
	}
	return &vo.AgentRegisterRes{
		Guid:   ag.GUID,
		Config: ag.ConfigRepoValue,
	}, nil
}

// GetConfig Agent启动配置查询，agent可以查询过去的启动配置
func (r *Agent) GetConfig(guid string) (interface{}, error) {
	return r.AgentFactory.GetConfig(guid)
}

// PutConfig Agent启动配置存储，agent可以将启动配置存储在总控
func (r *Agent) PutConfig(req vo.AgentPutConfigReq) error {
	return r.AgentFactory.PutConfig(req)
}

// FindAll 查询所有的agent
func (r *Agent) FindAll() (interface{}, error) {
	objs, err := r.AgentFactory.QueryAgentAll()
	if err != nil {
		return nil, err
	}
	return objs, nil
}

// FindAll 查询所有的agent
func (r *Agent) FindClusters() (interface{}, error) {
	objs, err := r.AgentFactory.QueryAgentAll()
	if err != nil {
		return nil, err
	}
	var res = make([]map[string]interface{}, len(objs))
	for k, v := range objs {
		res[k] = map[string]interface{}{
			"guid": v.GUID,
			"name": v.DetailRepoValue.ClusterName,
		}
	}
	return res, nil
}

// FindAll 根据条件查询agent
func (r *Agent) FindBy(query map[string]interface{}) (interface{}, error) {
	objs, err := r.AgentFactory.QueryAgent(query)
	if err != nil {
		return nil, err
	}
	return objs, nil
}

// Runtime 聚合查询agent运行时的信息
func (r *Agent) Runtime(organize int64) (interface{}, error) {
	return r.AgentFactory.ClusterRuntime(organize)
}

// Runtime 聚合查询agent运行时的信息
func (r *Agent) RuntimeChild(organize int64) (interface{}, error) {
	return r.AgentFactory.ClusterChildInfo(organize)
}

// Runtime 聚合查询agent运行时的信息
func (r *Agent) UpdateNodes(auth infra.AuthInfo) error {
	return r.AgentFactory.UpdateNodes(auth)
}

func NewAgentDomain() *Agent {
	domain := &Agent{}
	prepare.FetchDependency(&domain.AgentFactory)
	return domain
}
